#ifndef _COMM_HPP_
#define _COMM_HPP_

#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <cerrno>
#include <cstring>
#include <cstdio>

using namespace std;

#define PATHNAME "."
#define PROJ_ID 0x66
#define MAX_SIZE 4096

key_t getKey()
{
    key_t k = ftok(PATHNAME,PROJ_ID);  // 可以获取同样的一个key!
    if( k < 0) // 创建失败
    {
        // cint,cout,cerr -> stdin, stdout, stderr
        cerr << errno << " : "<<strerror(errno) << endl;
        exit(1);
    }
    return k;
}

int getShmHelper(key_t k, int flags)
{
    // k是要shmget,设置进入共享内存属性中的！用来标识该共享内存中，在内核中的唯一性！就相当于餐厅座位号6，就能找到唯一位置
    //  shmid  vs   key
    //  fd     vs   inode
    int shmid = shmget(k,MAX_SIZE,flags);
    if(shmid < 0) // 创建失败
    {
        cerr<<errno<<":"<<strerror(errno)<<endl;
        exit(2);
    }
    return shmid;
}

int getShm(key_t k) // 获取shmid
{
    return getShmHelper(k,IPC_CREAT);
}

int creatShm(key_t k) // 不存在的话就创建
{
    return getShmHelper(k,IPC_CREAT| IPC_EXCL | 0600);
}

void *attachShm(int shmid)
{
    void *mem = shmat(shmid,nullptr,0); // 64系统，8字节
    if((long long)mem == -1L) //转成 long long 是 0xffffffff（还是 -1）//不能是int,int是4字节 ，指针是8字节
    {
        cerr << "shmat: " << errno << " : " << strerror(errno) << endl;
        exit(3);
    }
    return mem;
}

void detachShm(void *start)
{
    if(shmdt(start) == -1)
    {
        cerr << "shmdt: " << errno << " : " << strerror(errno) << endl;
    }
}

void delShm(int shmid)
{
    if(shmctl(shmid,IPC_RMID,nullptr) == -1) // 返回值为-1则失败
    {
        cerr << errno << " : " << strerror(errno) << endl;
    }
}

#endif